/**
 *
 * @description: Proxy 和 Reflect
 * @author: junyong.hong
 * @createTime: 2018/3/28
 * @version: 1.0.0.0
 * @history:
 *    1、
 *    2、
 *
 */
{
    // 供应商 原始对象，存储真实数据
    let obj = {
        time:'2017-03-11',
        name:'net',
        _r:123
    };

    // 代理商
    let monitor = new Proxy(obj, {
        // 拦截（代理）对象属性的读取
        get(target, key){
            // target相当于obj
            // console.log(target);

            // 把2017替换成2018
            return target[key].replace('2017','2018');
        },
        // 拦截对象设置属性
        set(target, key, value){
            if(key === 'name'){
                return target[key] = value
            }else {
                return target[key];
            }

        },
        // 拦截key in object 操作
        has(target, key){
            if(key === 'name'){
                return target[key]
            }else{
                return false;
            }
        },
        // 拦截delete
        deleteProperty(target,key){
            if(key.indexOf('_') > -1){
                delete target[key];
                return true;
            }else{
                return target[key];
            }
        },
        // 拦截Object.keys, Object.getOwnPropertySymbols, Object.getOwnPropertyNames
        // 保护time的key不被用户看到
        ownKeys(target){
            return Object.keys(target).filter(item=>item!='time')
        }
    });

    console.log('get', monitor.time);       // 2018-03-11

    monitor.time = '2019';
    monitor.name = 'hjy';
    console.log('set',monitor.time);        // 2018-03-11
    console.log('set',monitor.name);        // hjy

    // time被拦截了  true false
    console.log('has','name' in monitor, 'time' in monitor);

    // 对象依旧存在
    // delete monitor.time;
    // console.log('delete', monitor);

    // 成功的删掉_r
    // delete monitor._r;
    // console.log('delete', monitor);

    console.log('ownKeys',Object.keys(monitor));
}

{
    let obj = {
        time:'2017-03-11',
        name:'net',
        _r:123
    };

    // 读取time的值
    console.log('Reflect get', Reflect.get(obj,'time'));    // 2017-03-11
    // 把name改成hjy
    Reflect.set(obj, 'name', 'hjy');
    console.log(obj);                                       // {time: "2017-03-11", name: "hjy", _r: 123}
    // 判断obj里是否有name
    console.log('has',Reflect.has(obj,'name'));             // true
}

{
    function validator(target, validator) {
        // 对target进行代理
        return new Proxy(target,{
            // 保存配置选项
            _validator:validator,
            // 对set进行修改
            set(traget,key,value,proxy){
                if(target.hasOwnProperty(key)){
                    let va = this._validator[key];
                    if(!!va(value)){
                        return Reflect.set(target,key,value,proxy);
                    }else{
                        throw Error(`不能设置${key}到${value}`)
                    }
                }else{
                    throw Error(`${key} 不存在`)
                }
            }
        })
    }

    const personValidators={
        name(val){
            return typeof val === 'string'
        },
        age(val){
            return typeof val === 'number' && val > 18
        }
    };

    class Person{
        constructor(name,age){
            this.name = name;
            this.age = age;
            return validator(this,personValidators)
        }
    }

    const person = new Person('hjy',30);
    console.log(person);

    // 不能设置数字
    // person.name = 48;
    person.name = 'oli';
    console.log(person);

}










